
import 'dart:math';
import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:simple_animations/simple_animations.dart';
import 'package:supercharged_dart/supercharged_dart.dart';
import 'package:supercharged/supercharged.dart';

void main() {
  runApp(new MaterialApp(home: Page()));
}

class Page extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => PageState();
}

class PageState extends State<Page> {

  final GlobalKey<MoleState> moleKey = new GlobalKey();

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
          child: Center(
            child: Mole(key: moleKey),
          )
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.sentiment_very_satisfied),
        onPressed: () {
          moleKey.currentState!.hitMole();
        },
      ),
    );
  }
}

class Mole extends StatefulWidget {
  @override
  MoleState createState() => MoleState();

  Mole({
    Key? key,
  }) : super(key: key);
}

class MoleState extends State<Mole> {
  /// "点"的List
  final List<MoleParticle> particles = [];

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 100,
      height: 100,
      child: _buildMole(),
    );
  }

  Widget _buildMole() {
    return LoopAnimation<int>(
      duration: 2.seconds,
      tween: ConstantTween(1),
      builder: (context, child, value) {
        // builder每一帧都会被调用，所以要再次清理点
        _manageParticleLifecycle();
        return Stack(
          clipBehavior: Clip.none,
          children: [
            ...particles.map((it) => it.buildWidget())
          ],
        );
      },
    );
  }

  /// 向List中插入"点"
  hitMole() {
    Iterable.generate(50).forEach(
            (i) => particles.add(MoleParticle())
    );
  }

  /// 管理颗粒的生命，清除超时的颗粒
  _manageParticleLifecycle() {
    particles.removeWhere((particle) {
      return particle.progress() == 1;
    });
  }

  @override
  void setState(fn) {
    if (mounted) {
      super.setState(fn);
    }
  }
}

enum _MoleProps { x, y, scale }

class MoleParticle {
  late Animatable<MultiTweenValues<_MoleProps>> tween;
  late Duration startTime;
  final duration = 0.5.seconds;

  MoleParticle() {
    var random = Random();
    double max_x = 300;
    double max_y = 300;
    final start_x = 0.0;
    final start_y = 0.0;
    final end_x = max_x * random.nextDouble() * (random.nextBool() ? 1 : -1);
    final end_y = max_y * random.nextDouble() * (random.nextBool() ? 1 : -1);

    tween = MultiTween<_MoleProps>()
      ..add(_MoleProps.x, start_x.tweenTo(end_x))
      ..add(_MoleProps.y, start_y.tweenTo(end_y))
      ..add(_MoleProps.scale, 1.0.tweenTo(0.0));

    startTime = DateTime.now().duration();
  }

  Widget buildWidget() {
    final MultiTweenValues<_MoleProps> values = tween.transform(progress());
    var alpha = 255 - (255 * progress()).toInt();
    return Positioned(
      left: values.get(_MoleProps.x),
      top: values.get(_MoleProps.y),
      child: Transform.scale(
        scale: values.get(_MoleProps.scale),
        child: Container(
          width: 100,
          height: 100,
          decoration: BoxDecoration(
              color: Colors.black.withAlpha(alpha),
              borderRadius: BorderRadius.circular(50)
          ),
        ),
      ),
    );
  }

  /// 计算"点"的生命周期
  double progress() {
    return ((DateTime.now().duration() - startTime) / duration)
        .clamp(0.0, 1.0)
        .toDouble();
  }
}
